package com.pai4j.common.util;


import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.swing.Java2DRenderer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class FreemarkerUtils {

    private static final int DEFAULT_DOTS_PER_PIXEL = 3;

    /***
     * 模板转图片
     * @param template
     * @param vars
     * 
     * @return
     * @throws Exception
     */
    public static BufferedImage turnImage(String template, Map<String, Object> vars, int width) throws Exception {
        return turnImage(template, vars, width, -1);
    }

    public static BufferedImage turnImage(String template, Map<String, Object> vars, int width, int height) throws Exception {
        // 获取模板
        String html = getTemplate(template, vars);
        // 画图
        byte[] bytes = html.getBytes();
        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(bin);
        Java2DRenderer renderer = new Java2DRenderer(document, width * DEFAULT_DOTS_PER_PIXEL, height == -1 ? height : height * DEFAULT_DOTS_PER_PIXEL);
        renderer.setRenderingHints(resetRenderingHints());
        SharedContext sharedContext = renderer.getSharedContext();
        sharedContext.setDotsPerPixel(DEFAULT_DOTS_PER_PIXEL);
        sharedContext.setDPI(500);
        return renderer.getImage();
    }

    /***
     * 抗齿轮
     * @return
     */
    private static Map resetRenderingHints() {
        Map renderingHints = new HashMap();
        renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        renderingHints.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        return renderingHints;
    }

    /***
     * 获取模板
     * @param template
     * @param map
     * @return
     * @throws IOException
     * @throws TemplateException
     */
    private static String getTemplate(String template, Map<String,Object> map) throws IOException, TemplateException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
        cfg.setTemplateLoader(new ClassTemplateLoader(new FreemarkerUtils().getClass().getClassLoader(),  "/templates/ftl/"));
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setLogTemplateExceptions(false);
        Template temp = cfg.getTemplate(template);
        StringWriter stringWriter = new StringWriter();
        temp.process(map, stringWriter);
        stringWriter.flush();
        stringWriter.close();
        return stringWriter.getBuffer().toString();
    }
}